package com.supermap.fabricsdk;

import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import org.hyperledger.fabric.protos.common.Common;
import org.hyperledger.fabric.sdk.Channel;
import org.hyperledger.fabric.sdk.TransactionInfo;
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
import org.hyperledger.fabric.sdk.exception.ProposalException;


import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.Principal;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.List;

/**
 * @author liqs
 * @version 1.0
 * @date 2020/7/10 15:22
 * 根据交易 ID 获取该交易的交易人
 * todo 其中还可以获取很多的其他信息，以后有需要在获取
 */
public class SmTxid {

    private Channel channel;

    public SmTxid(SmChain smChain){
        channel = smChain.getHFChannel();
    }

    public JSONObject getOrginfo(String txid){
        JSONObject jsonObject = new JSONObject();
        try {
            TransactionInfo transactionInfo = channel.queryTransactionByID(txid);
            Common.Envelope envelope = transactionInfo.getEnvelope();
            // 得到 交易信息
            ByteString payload = envelope.getPayload();
            // 交易信息转为 byteArray
            byte[] byteArray = payload.toByteArray();
            // 根据对应的 protobuf  的格式解析
            Common.Payload payload1 = null;
            try {
                payload1 = Common.Payload.parseFrom(byteArray);
            } catch (InvalidProtocolBufferException e) {
                e.printStackTrace();
            }
            // 获取交易新的 header
            Common.HeaderOrBuilder headerOrBuilder = payload1.getHeaderOrBuilder();
            ByteString signatureHeader = headerOrBuilder.getSignatureHeader();
            // 获取 header 里面的 ChannelHeader
            Common.Header header = Common.Header.parseFrom(signatureHeader.toByteArray());
            ByteString channelHeader1 = header.getChannelHeader();
            // 转为 字符串
            String s = channelHeader1.toStringUtf8();
            // 对 list 进行解析得到证书
            String certificate1 = getCertificate(s);
            // 对证书进行解析
            InputStream inputStream = new ByteArrayInputStream(certificate1.getBytes());
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate certificate = (X509Certificate) cf.generateCertificate(inputStream);
            Principal principal = certificate.getSubjectDN();
            String principalName = principal.getName();// 这里面获取具体的用户名
            Principal issuerDN = certificate.getIssuerDN();   // 这里面获取组织
            String issuerDNName = issuerDN.getName();
            String user = getUser(principalName);
            String org = getOrg(issuerDNName);
            jsonObject.put("Org", org);
            jsonObject.put("user", user);
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (InvalidArgumentException e) {
            e.printStackTrace();
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        } catch (ProposalException e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    /**
     * 解析证书
     * @param str
     * @return
     */
    private String getCertificate(String str){
        StringBuilder stringBuilder = new StringBuilder();
        // 写到临时文件
        try {
            String[] strings = str.split("\n");
            int line = 1;
            for (String s : strings) {
                if(line < 2){
                    line++;
                    continue;
                }
                if (line == 2) {
                    stringBuilder.append("-----BEGIN CERTIFICATE-----" + "\n");     // 因为是换行，所以采用StringBuilder追加形成
                } else {
                    stringBuilder.append(s + "\n");
                }
                line++;
            }
        }catch (Exception E){
        }
        return stringBuilder.toString();
    }

    // 获取用户信息
    private String getUser(String str){
        List<String> result = Arrays.asList(str.split(","));
        String cn = result.get(0);
        cn = cn.trim();
        while (cn.startsWith("　")) {
            cn = cn.substring(1, cn.length()).trim();
        }
        return cn.substring(3, cn.length());
    }

    // 获取组织信息
    private String getOrg(String str){
        List<String> result = Arrays.asList(str.split(","));
        String cn = result.get(1);
        cn = cn.trim();
        while (cn.startsWith("　")) {
            cn = cn.substring(1, cn.length()).trim();
        }
        return cn.substring(2, cn.length());
    }

}
